package com.mindskip.xzs.configuration.spring.security;
//Spring Security中的UserDetailsService实现类，主要作用是根据用户名加载用户的详细信息。
//当用户尝试登录系统时，Spring Security会调用loadUserByUsername方法，根据用户输入的用户名从数据库中获取用户信息。
//如果数据库中存在该用户，将用户信息封装成UserDetails对象并返回，包含用户名、密码和权限信息。
//如果数据库中不存在该用户，将抛出UsernameNotFoundException异常。
import com.mindskip.xzs.domain.enums.RoleEnum;
import com.mindskip.xzs.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.ArrayList;

/**
 * RestDetailsServiceImpl 实现了 UserDetailsService 接口
 * 这是一个 Spring 组件，用于根据用户名加载用户的详细信息
 */
@Component
public class RestDetailsServiceImpl implements UserDetailsService {

    private final UserService userService; // 用户服务，提供获取用户信息等功能

    /**
     * 构造函数，通过依赖注入初始化 userService
     * @param userService 用户服务
     */
    @Autowired
    public RestDetailsServiceImpl(UserService userService) {
        this.userService = userService;
    }

    /**
     * 根据用户名加载用户的详细信息
     * @param username 用户名
     * @return UserDetails 用户详细信息
     * @throws UsernameNotFoundException 当用户名未找到时抛出异常
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        // 通过用户名从数据库获取用户信息
        com.mindskip.xzs.domain.User user = userService.getUserByUserName(username);

        // 如果用户信息为空，抛出用户名未找到异常
        if (user == null) {
            throw new UsernameNotFoundException("Username not found.");
        }

        // 创建用于存放用户权限的集合
        ArrayList<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        // 根据用户角色添加相应的权限
        grantedAuthorities.add(new SimpleGrantedAuthority(RoleEnum.fromCode(user.getRole()).getRoleName()));

        // 返回包含用户名、密码和权限的 UserDetails 对象
        return new User(user.getUserName(), user.getPassword(), grantedAuthorities);
    }
}
